package org.chen.ctrip.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.chen.common.ctrip.entity.CustomDayContent;
import org.chen.common.ctrip.entity.Product;
import org.chen.ctrip.service.CustomDayContentService;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class HtmlContentProcessor {

    @Autowired
    private CustomDayContentService customDayContentService;

    /**
     * 处理HTML内容，替换第一天和最后一天的内容
     */
    public String processHtmlWithCustomContent(String originalHtml, Product product, String platform) {
        try {
            Document doc = Jsoup.parse(originalHtml);

            // 获取所有表格
            Elements tables = doc.select("table.print_table");

            if (tables.isEmpty()) {
                log.warn("未找到行程表格");
                return originalHtml;
            }

            log.info("开始处理商品{}的HTML内容，总天数：{}", product.getId(), product.getDurationDays());

            // 处理第一天
            boolean firstDayProcessed = processFirstDay(tables, product, platform);
            log.info("第一天处理结果：{}", firstDayProcessed ? "成功" : "失败");

            // 处理最后一天（只有当天数大于1时才处理最后一天）
            if (product.getDurationDays() > 1) {
                boolean lastDayProcessed = processLastDay(tables, product, platform);
                log.info("最后一天处理结果：{}", lastDayProcessed ? "成功" : "失败");
            }

            return doc.html();

        } catch (Exception e) {
            log.error("处理HTML内容失败", e);
            return originalHtml;
        }
    }

    /**
     * 处理第一天内容
     */
    private boolean processFirstDay(Elements tables, Product product, String platform) {
        try {
            log.info("查找第一天自定义内容，出发城市：{}，目的地：{}", product.getCity(), product.getLocations());

            CustomDayContent firstDayContent = customDayContentService.getMatchingContent(
                    platform, "first_day", product.getCity(), product.getLocations());

            if (firstDayContent == null) {
                log.info("未找到第一天的自定义内容，使用原内容");
                return false;
            }

            log.info("找到第一天自定义内容，ID：{}，内容长度：{}",
                    firstDayContent.getId(), firstDayContent.getContent().length());

            // 在所有表格中查找第一天
            for (Element table : tables) {
                Elements rows = table.select("tbody > tr");
                Element firstDayRow = findDayTitleRow(rows, 1);

                if (firstDayRow != null) {
                    log.info("找到第一天标题行");
                    return replaceContentAfterTitle(table, firstDayRow, firstDayContent.getContent(), 1);
                }
            }

            log.warn("未找到第一天标题行");
            return false;

        } catch (Exception e) {
            log.error("处理第一天内容失败", e);
            return false;
        }
    }

    /**
     * 处理最后一天内容
     */
    private boolean processLastDay(Elements tables, Product product, String platform) {
        try {
            log.info("查找最后一天自定义内容，出发城市：{}，目的地：{}", product.getCity(), product.getLocations());

            CustomDayContent lastDayContent = customDayContentService.getMatchingContent(
                    platform, "last_day", product.getCity(), product.getLocations());

            if (lastDayContent == null) {
                log.info("未找到最后一天的自定义内容，使用原内容");
                return false;
            }

            log.info("找到最后一天自定义内容，ID：{}，内容长度：{}",
                    lastDayContent.getId(), lastDayContent.getContent().length());

            // 在所有表格中查找最后一天
            for (Element table : tables) {
                Elements rows = table.select("tbody > tr");
                Element lastDayRow = findDayTitleRow(rows, product.getDurationDays());

                if (lastDayRow != null) {
                    log.info("找到最后一天标题行，天数：{}", product.getDurationDays());
                    return replaceContentAfterTitle(table, lastDayRow, lastDayContent.getContent(), product.getDurationDays());
                }
            }

            log.warn("未找到最后一天标题行，天数：{}", product.getDurationDays());
            return false;

        } catch (Exception e) {
            log.error("处理最后一天内容失败", e);
            return false;
        }
    }

    /**
     * 查找指定天数的标题行
     */
    private Element findDayTitleRow(Elements rows, int dayNumber) {
        for (Element row : rows) {
            Elements headerCells = row.select("th");
            if (!headerCells.isEmpty()) {
                String headerText = headerCells.first().text().trim();
                log.debug("检查标题行：'{}'，是否匹配Day {}", headerText, dayNumber);

                // 更灵活的匹配模式
                if (headerText.matches("Day\\s*0?" + dayNumber + "\\b") ||
                        headerText.matches("Day\\s+" + dayNumber + "\\b") ||
                        headerText.equals("Day " + dayNumber) ||
                        headerText.equals("Day" + dayNumber)) {
                    log.info("找到匹配的标题行：'{}'", headerText);
                    return row;
                }
            }
        }
        return null;
    }

    /**
     * 替换标题行之后的所有内容直到下一个Day标题
     */
    private boolean replaceContentAfterTitle(Element table, Element titleRow, String customContent, int dayNumber) {
        try {
            Elements allRows = table.select("tbody > tr");
            int titleIndex = allRows.indexOf(titleRow);

            if (titleIndex == -1) {
                log.error("无法找到标题行在表格中的位置");
                return false;
            }

            log.info("标题行位置：{}，总行数：{}", titleIndex, allRows.size());

            // 找到下一个Day标题的位置
            int nextDayIndex = findNextDayIndex(allRows, titleIndex + 1);
            log.info("下一个Day标题位置：{}", nextDayIndex);

            // 删除标题行和下一个Day标题之间的所有行
            int deletedCount = 0;
            for (int i = nextDayIndex - 1; i > titleIndex; i--) {
                allRows.get(i).remove();
                deletedCount++;
            }
            log.info("删除了{}行原内容", deletedCount);

            // 插入自定义内容
            return insertCustomContent(titleRow, customContent);

        } catch (Exception e) {
            log.error("替换Day{}内容失败", dayNumber, e);
            return false;
        }
    }

    /**
     * 查找下一个Day标题的索引
     */
    private int findNextDayIndex(Elements rows, int startIndex) {
        for (int i = startIndex; i < rows.size(); i++) {
            Element row = rows.get(i);
            Elements headerCells = row.select("th");
            if (!headerCells.isEmpty()) {
                String headerText = headerCells.first().text().trim();
                if (headerText.matches("Day\\s*\\d+")) {
                    log.debug("找到下一个Day标题：'{}'，位置：{}", headerText, i);
                    return i;
                }
            }
        }
        log.debug("未找到下一个Day标题，返回最后位置：{}", rows.size());
        return rows.size(); // 如果没找到下一个Day，返回最后位置
    }

    /**
     * 插入自定义内容
     */
    private boolean insertCustomContent(Element titleRow, String customContent) {
        try {
            log.info("开始插入自定义内容，内容长度：{}", customContent.length());
//            log.debug("自定义内容：{}", customContent);

            // 首先尝试作为HTML片段解析
            if (customContent.contains("<tr>") || customContent.contains("<td>")) {
                return insertHtmlCustomContent(titleRow, customContent);
            } else {
                // 作为纯文本内容处理
                return insertTextCustomContent(titleRow, customContent);
            }

        } catch (Exception e) {
            log.error("插入自定义内容失败", e);
            // 如果解析失败，尝试插入简单内容
            return insertSimpleCustomContent(titleRow, customContent);
        }
    }

    /**
     * 插入HTML格式的自定义内容
     */
    private boolean insertHtmlCustomContent(Element titleRow, String customContent) {
        try {
            log.info("开始解析HTML自定义内容");
//            log.debug("原始自定义内容：{}", customContent);

            // 清理和预处理内容
            String cleanedContent = customContent.trim();

            // 如果内容不是以<tr>开头，可能需要包装
            if (!cleanedContent.startsWith("<tr")) {
                log.warn("自定义内容不是以<tr>开头，尝试查找tr元素");
            }

            // 解析自定义内容 - 使用更完整的HTML结构
            String wrappedContent = "<html><body><table><tbody>" + cleanedContent + "</tbody></table></body></html>";
            Document customDoc = Jsoup.parse(wrappedContent);
            Elements customRows = customDoc.select("tbody tr");

            log.info("解析得到{}行自定义内容", customRows.size());

            if (customRows.isEmpty()) {
                log.warn("自定义内容中没有找到tr元素，尝试直接解析");
                // 尝试直接解析
                customDoc = Jsoup.parseBodyFragment(cleanedContent);
                customRows = customDoc.select("tr");

                if (customRows.isEmpty()) {
                    log.error("仍然没有找到tr元素，转为纯文本处理");
                    return insertTextCustomContent(titleRow, customContent);
                }
            }

            Element currentRow = titleRow;
            int insertedCount = 0;

            for (Element customRow : customRows) {
                try {
                    // 克隆行到目标文档
                    Element newRow = titleRow.ownerDocument().createElement("tr");

                    // 复制所有子元素
                    Elements cells = customRow.select("td");
                    for (Element cell : cells) {
                        Element newCell = newRow.appendElement("td");
                        // 复制所有属性
                        for (org.jsoup.nodes.Attribute attr : cell.attributes()) {
                            newCell.attr(attr.getKey(), attr.getValue());
                        }
                        // 复制内容
                        newCell.html(cell.html());
                    }

                    // 确保新行的格式符合原表格结构
                    formatCustomRow(newRow);

                    // 插入到DOM中
                    currentRow.after(newRow);
                    currentRow = newRow;
                    insertedCount++;

                    log.debug("成功插入第{}行自定义内容", insertedCount);

                } catch (Exception e) {
                    log.error("插入第{}行时出错", insertedCount + 1, e);
                    continue;
                }
            }

            if (insertedCount > 0) {
                log.info("成功插入{}行HTML自定义内容", insertedCount);
                return true;
            } else {
                log.error("没有成功插入任何自定义内容");
                return false;
            }

        } catch (Exception e) {
            log.error("插入HTML自定义内容失败", e);
            return insertTextCustomContent(titleRow, customContent);
        }
    }

    /**
     * 插入纯文本自定义内容
     */
    private boolean insertTextCustomContent(Element titleRow, String customContent) {
        try {
            // 创建一个新行包含文本内容
            Element newRow = titleRow.ownerDocument().createElement("tr");

            // 时间列（空）
            Element timeCell = newRow.appendElement("td");
            timeCell.appendElement("p").addClass("print_table_time");
            timeCell.appendElement("p").addClass("print_table_time_text");

            // 内容列
            Element contentCell = newRow.appendElement("td");
            contentCell.addClass("print_table_td_right");

            // 创建内容文本
            Element textDiv = contentCell.appendElement("div");
            textDiv.addClass("print_table_td_text");

            Element richContentDiv = textDiv.appendElement("div");
            richContentDiv.addClass("rich_content_view_20191129 desc break-words");
            richContentDiv.html(customContent.replace("\n", "<br>"));

            titleRow.after(newRow);

            log.info("成功插入纯文本自定义内容");
            return true;

        } catch (Exception e) {
            log.error("插入纯文本自定义内容失败", e);
            return false;
        }
    }

    /**
     * 格式化自定义行，确保符合原表格结构
     */
    private void formatCustomRow(Element row) {
        try {
            // 确保行有正确的结构
            Elements cells = row.select("td");

            if (cells.size() >= 2) {
                Element timeCell = cells.get(0);
                Element contentCell = cells.get(1);

                // 确保第二列有正确的样式类
                if (!contentCell.hasClass("print_table_td_right")) {
                    contentCell.addClass("print_table_td_right");
                }

                // 检查时间列是否有正确的结构
                if (timeCell.select("p.print_table_time").isEmpty()) {
                    // 如果没有时间结构，创建默认的
                    timeCell.html("<p class=\"print_table_time\"></p><p class=\"print_table_time_text\"></p>");
                }

                // 确保内容列有正确的结构
                Elements titleElements = contentCell.select("p.print_table_title");
                Elements textDivs = contentCell.select("div.print_table_td_text");

                // 如果结构不完整，但有内容，保持原样
                if (titleElements.isEmpty() && textDivs.isEmpty() && !contentCell.text().trim().isEmpty()) {
                    // 内容存在但结构不标准，包装一下
                    String originalContent = contentCell.html();
                    contentCell.html("<div class=\"print_table_td_text\">" +
                            "<div class=\"rich_content_view_20191129 desc break-words\">" +
                            originalContent + "</div></div>");
                }

            } else if (cells.size() == 1) {
                // 如果只有一列，可能需要调整
                log.warn("自定义行只有一列，可能格式不正确");
            }

            log.debug("格式化自定义行完成，单元格数量：{}", cells.size());

        } catch (Exception e) {
            log.error("格式化自定义行失败", e);
        }
    }

    /**
     * 插入简单的自定义内容（当其他方法都失败时的备用方案）
     */
    private boolean insertSimpleCustomContent(Element titleRow, String customContent) {
        try {
            Element newRow = titleRow.ownerDocument().createElement("tr");

            // 时间列
            Element timeCell = newRow.appendElement("td");
            timeCell.appendElement("p").addClass("print_table_time");
            timeCell.appendElement("p").addClass("print_table_time_text");

            // 内容列
            Element contentCell = newRow.appendElement("td");
            contentCell.addClass("print_table_td_right");
            contentCell.html("<div class=\"print_table_td_text\">" +
                    "<div class=\"rich_content_view_20191129 desc break-words\">" +
                    customContent.replace("\n", "<br>") +
                    "</div></div>");

            titleRow.after(newRow);

            log.info("成功插入简单自定义内容");
            return true;

        } catch (Exception e) {
            log.error("插入简单自定义内容失败", e);
            return false;
        }
    }
}